Notebook dedicado a la extracción de los metadatos geograficos y temporales. En el caso de los datos geográficos se enriquecerán aportando adicionalmente (distancia de residencia habitual, municipio y provincia)
import pickle
import math
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
# Packages propios
from utils.graphdbmanipulation import ImagesGraphDB
from utils.imagesmanipulation import ImageHelper
# Rutas de interés
PATH_IMAGENES_A_ANALIZAR = "c:/Users/dcsj/OneDrive/Formación/Masters & Postgrados/En Curso/UOC-Master en Ciencia de Datos/TFM/Imagenes/Movil-S21"
PATH_GML_FILE = 'c:/Users/dcsj/Repositorios/UOC_TFM/image_classifier/outputs/graphs/graph_GEO_TIME.gml'
# Coordenadas de residencia habitual
RESIDENCE_LATITUDE = 41.462435251362294
RESIDENCE_LONGITUDE = 2.203910532194043
Se van a extraer los datos del gps (latitud y longitud) de las imágenes en caso de que dispongan de esa información y la fecha de realización de la foto. A partir de la información de latitud y longitud, mediante el servicio https://nominatim.openstreetmap.org/reverse se van a obtener diversos datos adicionales:
Además, con los datos de longitud y latitud extraidos se calculará la distancia en km respecto de la que es considerada residencia habitual. Por último, se realizará la extracción de la fecha y hora, día, mes y año como información necesaria para estudios de frecuencias y periodos que puedan ayudar en la determinación de álbumes.
# Se crea el objeto con la clase que habilita la extracción y enriquecimiento de datos
imagehelper = ImageHelper()
geo_date_data = imagehelper.get_geo_and_date_images_data(PATH_IMAGENES_A_ANALIZAR,RESIDENCE_LATITUDE,RESIDENCE_LONGITUDE)
geo_date_data.head(10)
| filename | latitude | longitude | city | postcode | state_district | state | country | distance_km | datestring | day | month | year | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 20210724_100218.jpg | 41.458438 | 2.204826 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.450968 | 2021:07:24 10:02:18 | 24 | 7 | 2021 |
| 1 | 20210724_104730.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:31 | 24 | 7 | 2021 |
| 2 | 20210724_104736.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:36 | 24 | 7 | 2021 |
| 3 | 20210724_104739.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:39 | 24 | 7 | 2021 |
| 4 | 20210724_104743.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:44 | 24 | 7 | 2021 |
| 5 | 20210724_104757.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:57 | 24 | 7 | 2021 |
| 6 | 20210724_200143.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:43 | 24 | 7 | 2021 |
| 7 | 20210724_200145.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:45 | 24 | 7 | 2021 |
| 8 | 20210724_200231_02.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
| 9 | 20210724_200231_03.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
# Se guarda en un fichero csv el dataframe generado
geo_date_data.to_csv('.\outputs\csv\geo_date_data.csv')
# Se incorpora la información en un grafo y se guarda en un fichero gml
geo_date_data = pd.read_csv('.\outputs\csv\geo_date_data.csv',header=0)
imagesGraphDB = ImagesGraphDB()
for row in geo_date_data.itertuples():
#nodo imagen
node = str(row.filename)
imagesGraphDB.add_node(row.filename)
imagesGraphDB.set_attribute_to_node(row.filename,'type','image_filename')
if row.city!='unknown':
# Se añaden los atributos geográficos al nodo de imagen
imagesGraphDB.set_attribute_to_node(row.filename,'distance_km',str(row.distance_km))
imagesGraphDB.set_attribute_to_node(row.filename,'latitude',row.latitude)
imagesGraphDB.set_attribute_to_node(row.filename,'longitude',row.longitude)
# nodo municipio
imagesGraphDB.add_node(row.city)
imagesGraphDB.set_attribute_to_node(row.city,'type','municipio')
imagesGraphDB.add_edge(row.filename,row.city)
#nodo provincia
imagesGraphDB.add_node(row.state_district)
imagesGraphDB.add_edge(row.filename,row.state_district)
imagesGraphDB.set_attribute_to_node(row.city,'type','provincia')
imagesGraphDB.add_edge(row.city,row.state_district)
#nodo país
imagesGraphDB.add_node(row.country)
imagesGraphDB.add_edge(row.filename,row.country)
imagesGraphDB.set_attribute_to_node(row.country,'type','país')
imagesGraphDB.add_edge(row.state_district,row.country)
#nodo código postal
imagesGraphDB.add_node(row.postcode)
imagesGraphDB.add_edge(row.filename,row.postcode)
imagesGraphDB.set_attribute_to_node(row.postcode,'type','código postal')
#nodo dia
imagesGraphDB.add_node(row.day)
imagesGraphDB.add_edge(row.filename,row.day)
imagesGraphDB.set_attribute_to_node(row.day,'type','día')
#nodo mes
imagesGraphDB.add_node(row.month)
imagesGraphDB.add_edge(row.filename,row.month)
imagesGraphDB.set_attribute_to_node(row.month,'type','mes')
#nodo mes
imagesGraphDB.add_node(row.month)
imagesGraphDB.add_edge(row.filename,row.month)
imagesGraphDB.set_attribute_to_node(row.month,'type','mes')
#nodo año
imagesGraphDB.add_node(row.year)
imagesGraphDB.add_edge(row.filename,row.year)
imagesGraphDB.set_attribute_to_node(row.month,'type','año')
imagesGraphDB.write_gml_file(PATH_GML_FILE)
# Carga de resultados desde fichero csv
geo_date_data = pd.read_csv('.\outputs\csv\geo_date_data.csv',header=0)
geo_date_data.head(10)
| Unnamed: 0 | filename | latitude | longitude | city | postcode | state_district | state | country | distance_km | datestring | day | month | year | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 20210724_100218.jpg | 41.458438 | 2.204826 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.450968 | 2021:07:24 10:02:18 | 24 | 7 | 2021 |
| 1 | 1 | 20210724_104730.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:31 | 24 | 7 | 2021 |
| 2 | 2 | 20210724_104736.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:36 | 24 | 7 | 2021 |
| 3 | 3 | 20210724_104739.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:39 | 24 | 7 | 2021 |
| 4 | 4 | 20210724_104743.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:44 | 24 | 7 | 2021 |
| 5 | 5 | 20210724_104757.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:57 | 24 | 7 | 2021 |
| 6 | 6 | 20210724_200143.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:43 | 24 | 7 | 2021 |
| 7 | 7 | 20210724_200145.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:45 | 24 | 7 | 2021 |
| 8 | 8 | 20210724_200231_02.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
| 9 | 9 | 20210724_200231_03.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
# Filtrado de resultados para obtener solo los registros con datos de longitud y latitud
images_with_location = geo_date_data.loc[geo_date_data['latitude']>0]
images_with_location.head(10)
| Unnamed: 0 | filename | latitude | longitude | city | postcode | state_district | state | country | distance_km | datestring | day | month | year | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 20210724_100218.jpg | 41.458438 | 2.204826 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.450968 | 2021:07:24 10:02:18 | 24 | 7 | 2021 |
| 1 | 1 | 20210724_104730.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:31 | 24 | 7 | 2021 |
| 2 | 2 | 20210724_104736.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:36 | 24 | 7 | 2021 |
| 3 | 3 | 20210724_104739.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:39 | 24 | 7 | 2021 |
| 4 | 4 | 20210724_104743.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:44 | 24 | 7 | 2021 |
| 5 | 5 | 20210724_104757.jpg | 41.455110 | 2.202973 | Santa Coloma de Gramenet | 08924 | Barcelona | Catalunya | España | 0.818283 | 2021:07:24 10:47:57 | 24 | 7 | 2021 |
| 6 | 6 | 20210724_200143.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:43 | 24 | 7 | 2021 |
| 7 | 7 | 20210724_200145.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230864 | 2021:07:24 20:01:45 | 24 | 7 | 2021 |
| 8 | 8 | 20210724_200231_02.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
| 9 | 9 | 20210724_200231_03.jpg | 41.451868 | 2.208307 | Santa Coloma de Gramenet | 08921 | Barcelona | Catalunya | España | 1.230859 | 2021:07:24 20:02:31 | 24 | 7 | 2021 |
# Se trunca el valor de latitud y longitud a un decimal para hacer mapa de calor
truncate_factor = 10
images_with_location_truncated = geo_date_data.loc[geo_date_data['latitude']>0].copy()
images_with_location_truncated['latitude_truncated'] = images_with_location['latitude'].apply(lambda x: math.trunc(x*truncate_factor)/truncate_factor)
images_with_location_truncated['longitude_truncated'] = images_with_location['longitude'].apply(lambda x: math.trunc(x*truncate_factor)/truncate_factor)
images_with_location_truncated.head(10)
# Se agrupan por latitud y longitud para hacer un mapa de calor
df_grouped_area = images_with_location_truncated.groupby(['latitude_truncated','longitude_truncated']).size().reset_index(name='counts')
df_grouped_area.head(10)
| latitude_truncated | longitude_truncated | counts | |
|---|---|---|---|
| 0 | 40.7 | 0.2 | 55 |
| 1 | 40.8 | 0.1 | 175 |
| 2 | 40.8 | 0.2 | 24 |
| 3 | 40.8 | 0.8 | 7 |
| 4 | 41.1 | 1.5 | 64 |
| 5 | 41.1 | 1.6 | 6 |
| 6 | 41.3 | 2.0 | 4 |
| 7 | 41.3 | 2.1 | 99 |
| 8 | 41.4 | 2.1 | 6 |
| 9 | 41.4 | 2.2 | 133 |
# Se muestran los datos usando un mapbox
fig = px.density_mapbox(df_grouped_area, lat='latitude_truncated', lon='longitude_truncated', z='counts',
mapbox_style="stamen-terrain")
fig
# Se agrupa por día
df_grouped_date = geo_date_data.groupby(['year','month','day']).size().reset_index(name='counts')
df_grouped_date['date'] = df_grouped_date.apply(lambda x: str(x.year) +'_'+ str(x.month) +'_'+ str(x.day),axis=1)
df_grouped_date.sort_values(by='counts', ascending=False).head(10)
| year | month | day | counts | |
|---|---|---|---|---|
| 0 | 2018 | 5 | 5 | 3 |
| 1 | 2018 | 8 | 22 | 1 |
| 2 | 2018 | 8 | 24 | 1 |
| 3 | 2021 | 7 | 24 | 17 |
| 4 | 2021 | 7 | 25 | 33 |
| 5 | 2021 | 7 | 31 | 85 |
| 6 | 2021 | 8 | 2 | 1 |
| 7 | 2021 | 8 | 6 | 4 |
| 8 | 2021 | 8 | 7 | 7 |
| 9 | 2021 | 8 | 13 | 1 |
# Se realiza un histograma del 2021
df_grouped_date_2021 = df_grouped_date.loc[df_grouped_date['year']==2021]
fig, ax = plt.subplots(figsize=(20,5))
fig.suptitle('Number of images per day (2021)')
ax.bar(df_grouped_date_2021['date'],df_grouped_date_2021['counts'])
plt.xticks(rotation=30, ha='right')
plt.show()
Se observa como la frecuencia de fotografias aumenta de forma muy significativa en periodos de vacaciones y en fechas que coinciden con eventos como cenas, comidas y/o cumpleaños.